import 'dart:convert';
import 'dart:math';
import 'dart:ui';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
// ... 顶部 import 不变 ...
import 'package:share_plus/share_plus.dart';   // 确保已引入
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'package:flutter/rendering.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:speed_random/core/http/ws_app_test.dart';

// ... 其余 import ...
/// 通用方法 25-08-10
class commonFuc{
// 单例
static commonFuc instance = commonFuc();

  /* ===================== 新增：通用分享封装 ===================== */
  static final AudioPlayer _audioPlayer = AudioPlayer();

  /// 统一播放 MP3
  /// path: 要播放的文件 / 网络地址；为空则仅做停止
  /// stopAll: 是否先停止当前所有播放
  static Future<void> playMp3({
    String? path,
    bool stopAll = false,
  }) async {
    wsPrint('MP3 播放: $path');

    // 先停止当前播放
    await _audioPlayer.stop();
    if (stopAll) {
      return;
    }

    if (path == null || path.isEmpty) return;

    try {
      // 本地文件
      if (!path.contains('://')) {
        await _audioPlayer.play(AssetSource(path));
      } else {
        // 网络或 assets
        await _audioPlayer.play(UrlSource(path));
      }
    } catch (e) {
      wsPrint('MP3 播放失败: $e');
    }
  }



  /// 分享图片 + 文本
/// 微信中 分享 text 和 URL 都要传
/// final GlobalKey shareKey = GlobalKey(); // 添加这行
/// 需要截图的部分需要要用下面的组件包裹起来
/// RepaintBoundary(
/// key: shareKey,
/// child:
/// )

  static Future<void> shareImageWithText({
     GlobalKey? boundaryKey,
    required String text,
    String? subject,
    required String title,
    String? filePath,
    String? url,

  }) async {
    try {
     // Get.snackbar('tips', 'shareing…');

      if(boundaryKey != null){
      // 1. 截图
      final renderObject = boundaryKey?.currentContext?.findRenderObject();
      // 检查 renderObject 是否为 RenderRepaintBoundary 类型
      if (renderObject is! RenderRepaintBoundary) {
        wsPrint('关联的组件不是 RepaintBoundary 请用这个组件包裹');
        throw Exception('关联的组件不是 RepaintBoundary 请用这个组件包裹');
      }
      final boundary = renderObject;

      final image = await boundary.toImage();
      final byteData = await image.toByteData(format: ImageByteFormat.png);
      final pngBytes = byteData!.buffer.asUint8List();

      // 2. 保存临时文件
      final dir = await getTemporaryDirectory();
       filePath = '${dir.path}/share_${DateTime.now().millisecondsSinceEpoch}.png';
      final file = File(filePath);
      await file.writeAsBytes(pngBytes);
      }else if(filePath != null){
        final assetFilePath = AssetSource(filePath!);
        // 读取资源文件
        final byteData = await rootBundle.load(assetFilePath.path);
        final buffer = byteData.buffer;
        // 获取临时目录
        final tempDir = await getTemporaryDirectory();
        final tempFile = File('${tempDir.path}/${assetFilePath.path.split('/').last}');
        // 将资源文件写入临时文件
        await tempFile.writeAsBytes(
          buffer.asUint8List(byteData.offsetInBytes, byteData.offsetInBytes + byteData.lengthInBytes),
        );
        filePath = tempFile.path;
      }



      if(text !=null && url!=null){
        // 分享文本中添加链接  这里微信分享一定要这样 的格式，最后有链接才有文本+URL
        text = "$text\n$url";
        url=null;

      }
      wsPrint('title: $title');
      wsPrint('subject: $subject');
      wsPrint('text: $text');
      wsPrint('url: $url');
      wsPrint('filePath: $filePath');

      // 3. 调用系统分享
      final params = ShareParams(
        title: title ?? '',
        subject: subject ?? '',
        text: url == null ? text : null, // 如果 url 存在，不传入 text
        uri: url != null ? Uri.parse(url) : null, // 如果 url 存在，传入 uri

        files:filePath!=null?[XFile(filePath!)]:null,
      );
      await SharePlus.instance.share(params);

      //Get.snackbar('tips', 'Share ok');
    } catch (e) {
      Get.snackbar('tips', 'Share err: $e');
      wsPrint('Share err: $e');
    }
  }

  /* ===================== 原有 Share() 方法可删除 ===================== */




/// 16进制颜色转换为Color
/// 支持#和0x开头的16进制颜色字符串，例如：#ff0000和0xff0000
static Color hexToColor(String hexString) {
  if (hexString.isEmpty) {
    return Colors.transparent;
  }
  // 移除可能存在的#号
  final buffer = StringBuffer();
  if (hexString.length == 6 || hexString.length == 7) {
    buffer.write('ff'); // 添加不透明度
  }
  buffer.write(hexString.replaceFirst('#', ''));
  return Color(int.parse(buffer.toString(), radix: 16));
}
/// 计算字符串在给定宽度下的最大字体大小
  /// 确保字符串在一行内显示，不超过最大宽度
  /// 可以根据需要调整 baseSize 和 reductionFactor
  /// 添加这个辅助方法到你的 Widget 类中
  /// 调用示例：
  /// double fontSize = calculateFontSize('123456', context);
  static double calculateFontSize(String str,context,{double baseSize=300,reductionFactor=0.8}) {
   int digitCount=str.length;
  // 基础大小
  //const double baseSize = 300.0;
  // 每增加一位数字，字体大小减少的比例
  //const double reductionFactor = 0.8; // 调整为0.7使字体缩小更快

  // 计算最大可能字体大小，确保只显示一行
  final maxWidth = MediaQuery.of(context).size.width * 0.9; // 考虑90%的屏幕宽度
  final calculatedSize = baseSize * pow(reductionFactor, digitCount - 1);

  // 确保字体不超过最大宽度且不小于12
  return max(min(calculatedSize, maxWidth / digitCount), 12.0);
}
/// 生成唯一ID
  static String getRandomId({int number=16}) {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    final random = Random();
    return String.fromCharCodes(
      Iterable.generate(number, (_) => chars.codeUnitAt(random.nextInt(chars.length))),
    );
  }
  /// 生成唯一设备标识 （可以使用设备 ID、广告 ID 等）   这个方法可以在应用启动时调用，获取设备唯一标识，然后存储在 SharedPreferences 中。
  static Future<String> generateDeviceId() async{
    final prefs = await SharedPreferences.getInstance();
    String? advertisingId = prefs.getString('useradid');
    if (advertisingId!=null) {
      return advertisingId;
    }
    // 获取广告唯一 ID
    try {
      final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();

      if (defaultTargetPlatform == TargetPlatform.android) {
        final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
        advertisingId = androidInfo.id;
      } else if (defaultTargetPlatform == TargetPlatform.iOS) {
        final IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
        advertisingId = iosInfo.identifierForVendor;
      }

    } catch (e) {
      const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      final random = Random();
      advertisingId= String.fromCharCodes(
        Iterable.generate(16, (_) => chars.codeUnitAt(random.nextInt(chars.length))),
      );
    }

    // 确保 advertisingId 不为 null 并返回
    advertisingId ??= String.fromCharCodes(
      Iterable.generate(16, (_) => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.codeUnitAt(Random().nextInt(62))),
    );
    await prefs.setString('useradid', advertisingId);
    return advertisingId;

  }

  /// 格式化 DateTime 对象为 Y-m-d H:i:s 格式的字符串
  /// 调用示例：
  /// String formattedDate = formatDateTime(DateTime.now());
  /// 2023-08-24 14:30:45
  static  String formatDateTime(DateTime dateTime) {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    return '${dateTime.year}-${twoDigits(dateTime.month)}-${twoDigits(dateTime.day)} '
        '${twoDigits(dateTime.hour)}:${twoDigits(dateTime.minute)}:${twoDigits(dateTime.second)}';
  }
  /// 获取当前时间并格式化为 Y-m-d H:i:s 格式
  /// 调用示例：
  /// String formattedDate = getNowTimeYmdHis();
  /// 2023-08-24 14:30:45
  static String getNowTimeYmdHis() {
    return formatDateTime(DateTime.now());
  }
  /// 给传入的字符串补零，使其长度达到指定长度
  /// 调用示例：
  /// String paddedStr = add0('123', len: 4);
  /// 0123
  static String add0(str,{int len=2}) {
    String strValue = str.toString();
    while (strValue.length < len) {
      strValue = '0' + strValue;
    }
    return strValue;
  }
  /// 数组求和
  /// 调用示例：
  /// int sum = sumNumbers([1, 2, 3, 4, 5]);
  /// 15
  static int sumNumbers(List<dynamic> nums) {
    num sum = 0;
    for (var item in nums) {
      if (item is num) {
        sum += item;
      } else {
        // 尝试将各种类型转换为数字
        final converted = _tryConvertToNum(item);
        if (converted != null) {
          sum += converted;
        }
      }
    }
    return sum.toInt();
  }

  static num? _tryConvertToNum(dynamic value) {
    if (value is num) return value;
    if (value is String) return num.tryParse(value);
    if (value is bool) return value ? 1 : 0;
    if (value == null) return 0;
    return null;
  }

  /// 倒计时
  /// 调用示例：
  /// var countDown = TimeCountDown(60);
  /// 倒计时 60 秒
  /// 每 5 秒调用一次回调函数
  /// 倒计时结束后，打印 "倒计时结束"
  /// 倒计时结束后，打印 "倒计时结束"
  static TimeCountDown(itime,{int period=5,Function? fun,String d0="",String H0="open",String i0="ing",String s0="…"}){
  int d1;
  int H1;
  int i1;
  int s1;
  d1=itime~/86400;
  H1=(itime)~/3600;
  i1=((itime)%3600)~/60;
  s1=(itime)%60;
  var returndata={"d":d1<10?"0${d1}":"${d1}","H":H1<10?"0${H1}":"${H1}","i":i1<10?"0${i1}":"${i1}","s":s1<10?"0${s1}":"${s1}","itime":itime,"isrun":false};

  if(itime<0){
     returndata={"d":d0,"H":H0,"i":i0,"s":s0,"itime":itime,"isrun":false};
    if(itime%period==0){
      returndata["isrun"]=true;
      if(fun!=null)fun(returndata);
    }
  }

  return returndata;
}

  /// 截取字符串
  /// 调用示例：
  /// String content = 'Hello, World!';
  /// String result = BetWeenString(content, start: ',', end: '!');
  /// World
  static BetWeenString(String content,{String  start='',String end=''}){
  var endIndex=end==''?99999999:content.indexOf(end);
  var startIndex=start==''?0: content.indexOf(start);
  if(endIndex==-1 || startIndex==-1){
    return '';
  }

  return Mysubstring(content,startIndex,endIndex+1);
}

  /// 截取字符串
  /// 调用示例：
  /// String content = 'Hello, World!';
  /// String result = BetWeenString(content, start: ',', end: '!');
  /// World
  static Mysubstring(content,int startIndex, [int? endIndex]){
  String content1="${content}";
  if(startIndex>=0){
    return content1.substring(startIndex,endIndex);
  }else{
    return content1.substring(content1.length+startIndex);
  }

}

  /// 获取本地存储数据
  /// 调用示例：
  /// String? value = await getHostInstanceSave('key');
  /// 打印 value
  static getHostInstanceSave(String key,{String type='String',Function? fun})async{

  SharedPreferences prefs = await SharedPreferences.getInstance();

  var status;
  switch (type)
  {
    case 'String':
      status = prefs.getString(key);
      break;
    case 'Bool':
      status = prefs.getBool(key);
      break;
    case 'SList':
      status = prefs.getStringList(key);
      break;
    case 'Int':
      status = prefs.getInt(key);
      break;
    case 'Double':
      status = prefs.getDouble(key);
      break;
    case 'Map':
      var d=prefs.getString(key);
      status =d==null?null:jsonDecode(d);
      break;
    default:
      status = prefs.get(key);
  }
  if(fun!=null)fun(status);

}

  /// 保存本地存储数据
  /// 调用示例：
  /// await setHostInstanceSave('key', 'value');
  static setHostInstanceSave(String key,value,{String type='String',Function? fun})async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  var status;
  switch (type) {
    case 'String':
      status = prefs.setString(key, value);
      break;
    case 'Bool':
      status = prefs.setBool(key, value);
      break;
    case 'Double':
      status = prefs.setDouble(key, value);
      break;
    case 'Int':
      status = prefs.setInt(key, value);
      break;
    case 'SList':
      status = prefs.setStringList(key, value);
      break;
    case 'Map':
      status = prefs.setString(key, jsonEncode(value));
      break;
    default:
      status = prefs.setString(key, value);
  }
  if(fun!=null)fun(status);
}


}